<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            li {
                line-height: 100px;
                height: 100px;
            }
        </style>
    </head>
    <body>
        <p>参考：https://zhuanlan.zhihu.com/p/87591677</p>
        <button id="btn">点击</button>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <ul>
            <li>aaaa</li>
            <li>bbb</li>
            <li>cc</li>
            <li>d</li>
        </ul>
        <script>
            // 时间戳判断
            // 第一次会立即执行回调方法
            // 最后一次时间范围内不会执行
            function throttle_times(func, wait) {
                let last = 0;
                return function () {
                    let now = Date.now();
                    if (now - last >= wait) {
                        last = now;
                        func.call(this, arguments);
                    }
                };
            }

            // 定时器方式
            // 第一次不是立即执行，会延时执行
            // 最后一次时间范围内不会执行
            function throttle_after(func, wait) {
                var timeout, context;
                return function () {
                    let context = this;
                    let args = arguments;
                    let result;
                    if (!timeout) {
                        // 没有定时任务就添加一次任务
                        timeout = setTimeout(function () {
                            result = func.apply(context, args);
                            timeout = null;
                        }, wait);
                    }
                    return result;
                };
            }

            // 0-----10-----20-----30-34---40
            // 第一次 立即执行
            // 最后一次 延时执行
            function throttle(func, wait) {
                let timer = null;
                let last = Date.now();
                console.log('throttle()', last);

                return function () {
                    let context = this;
                    let args = arguments;
                    let now = Date.now();
                    let remainning = wait - (now - last); // 剩余多久之后才执行
                    console.log(now, remainning);

                    clearTimeout(timer);
                    if (remainning <= 0) {
                        console.log('立即执行-----');
                        //  间隔时间 超出定时
                        func.apply(context, args);
                        last = now;
                    } else {
                        // 间隔时间内
                        console.log('延时执行=====');
                        timer = setTimeout(func, remainning);
                    }
                };
            }

            function throttleoo(func, wait) {
                let timer = null;
                let last = Date.now();

                return function () {
                    let context = this;
                    let args = arguments;
                    let now = Date.now();
                    let remainingTimes = wait - (now - last);
                    if (remainingTimes <= 0) {
                        last = now;
                        func.apply(context, args); // func();
                    } else {
                        timer = setTimeout(func, remainning);
                    }
                };
            }

            // 处理函数
            function handle(a) {
                console.log('~~~~~~~~~~~~~~~~~~~', Date.now(), a);
            }

            // 滚动事件
            window.addEventListener(
                'scroll',
                throttle(function () {
                    handle(Math.floor((Math.random() * 100) / 10));
                }, 1000)
            );
        </script>
    </body>
</html>
